home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / PAPTool / PAPTool.cp < prev    next >
Encoding:
Text File  |  1992-11-29  |  8.1 KB  |  393 lines  |  [TEXT/MPS ]

  1. //    ©1992 Conrad Carlen & Manuel Veloso. All rights reserved.
  2.  
  3. #ifndef __TYPES__
  4. #include <Types.h>
  5. #endif
  6.  
  7. #ifndef __EXCEPTIONS__
  8. #include <Exceptions.h>
  9. #endif
  10.  
  11. #ifndef __APPLETALK__
  12. #include <AppleTalk.h>
  13. #endif
  14.  
  15. #ifndef __ERRMGR__
  16. #include <ErrMgr.h>
  17. #endif
  18.  
  19. #ifndef __Fonts__
  20. #include <Fonts.h>
  21. #endif
  22.  
  23. #ifndef __CURSORCTL__
  24. #include <CursorCtl.h>
  25. #endif
  26.  
  27. #ifndef __STRINGS__
  28. #include <Strings.h>
  29. #endif
  30.  
  31. #ifndef __CTYPE__
  32. #include <ctype.h>
  33. #endif
  34.  
  35. #ifndef __STDLIB__
  36. #include <stdlib.h>
  37. #endif
  38.  
  39. #ifndef __IOSTREAM__
  40. #include <iostream.h>
  41. #endif
  42.  
  43. #ifndef __FSTREAM__
  44. #include <fstream.h>
  45. #endif
  46.  
  47. #ifndef __IOMANIP__
  48. #include <iomanip.h>
  49. #endif
  50.  
  51. #ifndef _IDLE_
  52. #include "idle.h"
  53. #endif
  54.  
  55. #ifndef _PAPFILE_
  56. #include "Papfile.h"
  57. #endif
  58.  
  59. #ifndef _PAPTOOL_
  60. #include "Paptool.h"
  61. #endif
  62.  
  63. #ifndef _PAPPATCH_
  64. #include "Pappatch.h"
  65. #endif
  66.  
  67. #ifndef _PREPROCESS_
  68. #include "Preprocess.h"
  69. #endif
  70.  
  71. char *copyright = "©1992 Conrad Carlen & Manuel Veloso. All rights reserved.";
  72.  
  73. CPapFile    *theFile = nil;
  74.  
  75. ofstream    out;            // globalized
  76. ifstream    input;            // globalized because of error: << sorry, not implemented: label in block with destructors >>
  77. Boolean        gStdin = false;    // set to true if stdin is the file
  78. char        errMsg[255];    // global error msg buffer
  79. Boolean        gPatchInstalled;// set to true if patch was installed.
  80.  
  81. #pragma segment Initialize
  82. void initTool(void)
  83. {
  84.     SetFScaleDisable(true);
  85.     InitCursorCtl(nil);
  86.     InitErrMgr(nil, nil, true);
  87. }
  88.  
  89. #pragma segment Initialize
  90. void usage(void)
  91. {
  92.     out << "### Usage: PAPTool -n ObjectName -t ObjectType [-z ObjectZone] [files…]" << endl << endl;
  93. }
  94.  
  95. #pragma segment Initialize
  96. OSErr extractName(short argc, char *argv[], short &files, EntityName &thePrinter)
  97. {
  98.     short    parms;
  99.     short    length;
  100.     Str32    objStr, typeStr, zoneStr;
  101.     Boolean    name = false, type = false, zone = false;
  102.  
  103.     for (parms = 1; parms < argc; parms++)
  104.     {
  105.         length = strlen(argv[parms]);
  106.         if (*argv[parms] != '-') files++;
  107.         else if (tolower(*(argv[parms] + 1)) == 'n' && length == 2)
  108.         {
  109.             argv[parms] = 0;
  110.             strcpy((char *) &objStr[0], argv[++parms]);
  111.             argv[parms] = 0;
  112.             name = true;
  113.         }
  114.         else if (tolower(*(argv[parms] + 1)) == 't' && length == 2)
  115.         {
  116.             argv[parms] = 0;
  117.             strcpy((char *) &typeStr[0], argv[++parms]);
  118.             argv[parms] = 0;
  119.             type = true;
  120.         }
  121.         else if (tolower(*(argv[parms]+1)) == 'z' && length == 2)
  122.         {
  123.             argv[parms] = 0;
  124.             strcpy((char *) &zoneStr[0], argv[++parms]);
  125.             argv[parms] = 0;
  126.             zone = true;
  127.         }
  128.         else
  129.         {
  130.             out << "### " << argv[0] << " " << argv[parms] << " is not an option." << endl;
  131.             usage();
  132.             return 1;
  133.         }
  134.     }
  135.     
  136.     if (!name)
  137.     {
  138.         out << "### " << argv[0] << " Error: no name was specified." << endl;
  139.         usage();
  140.         return 1;
  141.     }
  142.     
  143.     if (!type)
  144.     {
  145.         out << "### " << argv[0] << " Error: no type was specified." << endl;
  146.         usage();
  147.         return 1;
  148.     }
  149.     
  150.     if (!zone)
  151.     {
  152.         strcpy((char *) &zoneStr[0], "*");
  153.     }
  154.     
  155.     c2pstr((char *) &objStr[0]);
  156.     c2pstr((char *) &typeStr[0]);
  157.     c2pstr((char *) &zoneStr[0]);
  158.     NBPSetEntity((Ptr) &thePrinter, (Ptr) &objStr[0], (Ptr) &typeStr[0], (Ptr) &zoneStr[0]);
  159.     return 0;
  160. }
  161.  
  162. #pragma segment Main
  163. void cleanup(void)
  164. {
  165.     long    myA5 = myGetA5();
  166.     long    oldA5 = SetA5(myA5);
  167.  
  168.     if (theFile)
  169.     {
  170.         delete theFile;            // note: theFile->Close checks for non-open files,
  171.     }
  172.     theFile = nil;                // doing this isn't a problem
  173.     if (gPatchInstalled)
  174.     {
  175.         removePatch();
  176.     }
  177.     SetA5(oldA5);
  178. }
  179.  
  180. #pragma segment Main
  181. short main(short argc, char *argv[])
  182. {
  183.     OSErr        error;
  184.     short        numFiles = 0, i;
  185.     EntityName    targetPrinter;
  186.     
  187.     initTool();
  188.  
  189.     out.attach(1);                                    // attach out to stdout
  190.  
  191.     nrequire_action(out.fail(), out_attach_1, cerr << "### Unable to attach to stdout!" << endl;);
  192.     
  193.     out.setf(1, ios::unitbuf);                        // flush after each lf
  194.     error = extractName(argc, argv, numFiles, targetPrinter);
  195.     nrequire_action(error, extract_name, out << "### Unable to extract name!" << endl;);
  196.     
  197.     theFile = new CPapFile;
  198.     error = theFile->IPapFile();
  199.     nrequire_action(error, thefile_ipapfile, out << "### Unable to create CPapFile!" << endl;);                        // no creation of pap object!
  200.     
  201.     error = openPrinter(targetPrinter);
  202.     nrequire(error, open_printer);
  203.     
  204.     atexit(cleanup);
  205.     
  206.     error = installPatch();                            // installs the hooks for PAPRead! Removed @exit
  207.     require_action(error, install_patch, out << "### Unable to install read patch!" << endl;);
  208.     
  209.     error = DoIt(argc, argv, numFiles, input, out);
  210.     nrequire(error, doit);
  211.     
  212.     theFile->Close();
  213.     out << "### Printer closed. ###" << endl;
  214.     return error;
  215. doit:
  216. install_patch:
  217.     theFile->Close();
  218. open_printer:
  219. thefile_ipapfile:
  220. extract_name:
  221.     out << "### " << " Error processing file " << argv[0] << endl;
  222.     if (error < 0)
  223.     {
  224.         out << "### " << GetSysErrText(error, errMsg) << endl;
  225.     }
  226. out_attach_1:
  227.     return 1;
  228. }
  229.  
  230. #pragma segment Initialize
  231. OSErr openPrinter(EntityName &thePrinter)
  232. {
  233.     OSErr error;
  234.     error = theFile->Open(thePrinter);
  235.     if (error >= 0)
  236.     {
  237.         while (theFile->GetOpenStatus() > 0)
  238.         {
  239.             idle();
  240.         }
  241.         error = theFile->GetLastReadErr();
  242.     }
  243.     
  244.     nrequire_action
  245.             ((((theFile->GetOpenStatus() < 0)) || (error != 0)), thefile_open,
  246.             (
  247.             out 
  248.             << "### Unable to open printer! Name: " 
  249.             << p2cstr(theFile->GetPrinterName()) 
  250.             << " Type: " << p2cstr(theFile->GetPrinterType()) 
  251.             << " Zone: " << p2cstr(theFile->GetPrinterZone()) 
  252.             << " ! ###" << endl
  253.             );
  254.             );
  255.     out << endl << "### The printer has been opened. ###" << endl;
  256. thefile_open:
  257.     return error;
  258. }
  259.  
  260. #pragma segment Main
  261. short getData(char *theBuffer, short bufferSize, ifstream &input)
  262. {
  263.     short count;
  264.     if (gStdin)
  265.     {
  266.         input.getline(theBuffer, bufferSize);
  267.         count = input.gcount();
  268.         count = preprocessWrite(theBuffer, count);
  269.     }
  270.     else
  271.     {
  272.         input.read(theBuffer, bufferSize);
  273.         count = input.gcount();
  274.     }
  275.     return count;
  276. }
  277.  
  278. #pragma segment Main
  279. OSErr DoIt(short argc, char *argv[], short numFiles, ifstream &input, ofstream &output)
  280. {
  281.     short    i;
  282.     OSErr    error;
  283.     if (numFiles == 0)
  284.     {
  285.         gStdin = true;
  286.         input.attach(0);
  287.         nrequire_action(input.fail(), input_attach, out << "### Unable to attach to stdin!" << endl;);
  288.     
  289.         input.setf(0, ios::skipws);                        // don’t skip whitespace
  290.         out << "### Ready for input. ###" << endl;
  291.         error = processFile(input, *theFile);
  292.         nrequire_action(error, process_file_1, out << "### ProcessFile error!" << endl;);
  293.     }
  294.     else
  295.     {
  296.         gStdin = false;
  297.         for (i = 1; (i < argc) && numFiles; i++)
  298.         {
  299.             if (argv[i])
  300.             {
  301.                 numFiles--;
  302.                 input.open(argv[i]);
  303.                 nrequire_action(input.fail(), input_open, out << "### Unable to open file: " << argv[1] << " ###" << endl;);
  304.                 
  305.                 input.setf(0, ios::skipws);                        // don’t skip whitespace. It doesn’t matter here, tho
  306.                 out << "### Processing file " << argv[i] << " ###" << endl;
  307.                 error = processFile(input, *theFile);
  308.                 nrequire_action(error, process_file_2, out << "### ProcessFile error! ###" << endl;);
  309.                 
  310.                 input.close();
  311.             }
  312.         }
  313.     }
  314.     return error;
  315. process_file_1:
  316.     input.close();
  317. input_attach:
  318.     return error;
  319. process_file_2:
  320.     input.close();
  321. input_open:
  322.     return error;
  323. }
  324.  
  325. #pragma segment Main
  326. OSErr processFile(ifstream &input, CPapFile &theFile)
  327. {
  328.     OSErr    error = noErr;
  329.     short    bufferSize = theFile.GetWriteSize();
  330.     char    *bufferAddr = theFile.GetWriteBufferAddress();
  331.     int        count;
  332.     
  333.     while (!input.eof())
  334.     {
  335.         count = getData(bufferAddr, bufferSize, input);
  336.         theFile.SetWriteCount(count);
  337.         error = theFile.Write();
  338.         if (error) break;
  339.  
  340.         if (!out.fail())
  341.         {
  342.             while (theFile.GetWriteStatus() > 0)
  343.             {
  344.                 idle();
  345.             }
  346.         }
  347.         if (error = theFile.GetLastWriteErr()) break;
  348.     }
  349.     return error;
  350. }
  351.  
  352. #pragma segment Initialize
  353. Boolean installPatch(void)
  354. {
  355.     Install(checkRead, SetCurrentA5());
  356.     gPatchInstalled = true;
  357. }
  358.  
  359. #pragma segment Initialize
  360. Boolean removePatch(void)
  361. {
  362.     Remove();
  363.     gPatchInstalled = false;
  364. }
  365.  
  366. #pragma segment Main
  367. void checkRead(void)
  368. {
  369.     long    myA5 = myGetA5();
  370.     long    oldA5 = SetA5(myA5);
  371.     OSErr    error = theFile->GetLastReadErr();
  372.  
  373.     if (error)
  374.     {
  375.         out << "### Read error!" << GetSysErrText(error, errMsg) << " ###" << endl;
  376.         out << "### Terminating! ###" << endl;
  377.         SetA5(oldA5);
  378.         exit(1);
  379.     }
  380.     if (theFile->GetReadStatus() <= 0)
  381.     {
  382.         short    count = theFile->GetReadCount();
  383.         char    *buffer = theFile->GetReadBufferAddress();
  384.         
  385.         count = preprocessRead(buffer, count, theFile->GetWriteBufferAddress());
  386.         out.write(buffer, count);
  387.         out.flush();
  388.         theFile->Read();
  389.     }
  390.     SetA5(oldA5);
  391.     return;
  392. }
  393.